﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using devtm.Editor.TypeSelector;
using Microsoft.VisualStudio.Modeling;
using DslModeling = global::Microsoft.VisualStudio.Modeling;
using devtm.AutoMapper;

namespace devtm.Editor.TypeSelector
{
    public class SolutionTypeProvider : ITypeProvider
    {


        public SolutionTypeProvider()
        {
            SourceTypes.Source.Add(this);
        }


        public IEnumerable<Type> GetTypes(DslModeling.Store store, HashSet<String> namespaces)
        {
            var i = TypeHelper.GetAvailableTypes<Object>(store)
                .Where(c => Valid(namespaces, c)).ToList();
            return i;
        }

        private static bool Valid(HashSet<String> namespaces, Type c)
        {

            if (c != null)
            {
                bool test = (c.IsPublic || c.IsNestedPublic);

                if (test)
                {

                    if (namespaces == null)
                        return true;

                    if (namespaces.Count == 0)
                        return true;

                    return namespaces.Contains(c.Namespace);

                }
            }

            return false;

        }


        public IEnumerable<Type> GetTypes(DslModeling.Store store, HashSet<String> namespaces, Func<Type, bool> filter)
        {

            if (store == null)
                yield break;

            foreach (Type item in GetTypes(store, namespaces))            
                if (filter(item))
                    yield return item;
            
        }

                
        #region Disposable

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~SolutionTypeProvider()
        {
            Dispose(false);
        }

        // The bulk of the clean-up code is implemented in Dispose(bool)
        protected virtual void Dispose(bool disposing)
        {

            if (disposing)
            {
                // free managed resources
            
            }

            SourceTypes.Source.Remove(this);

        }

        #endregion

    }
}
